﻿

//////////////////////////////////////////////////////////////////////////////
//
// Copyright © 1998-2024 Glodon Company Limited.
//
// Permission is hereby granted, free of charge, to any person obtaining a
// copy of this software and associated documentation files (the “Software”),
// to deal in the Software without restriction, including without limitation
// the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or
// sell copies of the Software, and to permit persons to whom the Software is
// furnished to do so, subject to the following conditions:
//
// The above copyright notice and this permission notice shall be included in
// all copies or substantial portions of the Software.
//
// THE SOFTWARE IS PROVIDED “AS IS”, WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
// THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
//
//////////////////////////////////////////////////////////////////////////////
#ifndef PROPERTYINSTANCPROPERTYSWIDGET_H
#define PROPERTYINSTANCPROPERTYSWIDGET_H
#pragma once

#include <QFrame>
#include <memory>
#include <QString>
#include <stdint.h>
#include "SampleShared.h"
#include <qttreepropertybrowser.h>
#include "PropertyInstanceSetting.h"

class QHBoxLayout;
class QtVariantPropertyManager;
class QtVariantEditorFactory;
class QtTreePropertyBrowser;
class QtProperty;

namespace Sample
{
    class CPropertyInstanceSetting;
    class CPropertyGroupItem;
    class CPropertyItem;

    /*!
    *@class CInstancePropertyWidget
    *@brief 实例属性窗口
    *
    */
    class SAMPLESHARED_EXPORT CInstancePropertyWidget : public QFrame
    {
        Q_OBJECT
    public:
        /*!
        *@brief      构造函数
        */
        CInstancePropertyWidget(int nWidth, int nHeight, CPropertyInstanceSetting *pPropertyInstanceSetting, QWidget *pParent = 0);
        /*!
        *@brief      析构函数
        */
        virtual ~CInstancePropertyWidget();
        /*!
        *@brief      获取属性实例的基本信息
        *@param [in] CPropertyInstanceSetting *pPropertyInstanceSetting
        *@return     CPropertyInstanceSetting*
        */
        CPropertyInstanceSetting *GetPropertyInstanceSetting() const;
        /*!
        *@brief      设置属性实例的基本信息，若当前界面已经展示则会有一个再激活的过程
        *@return     void
        */
        void RefreshView(bool bRebuild = false);
        /*!
        *@brief                                      指定索引处插入属性组
        *@param [in] int index                      指定索引
        *@param [in] int uniqueID               唯一标识
        *@param [in] const QString & name           属性组名称
        *@param [in] const QString & description    属性组描述
        *@return CPropertyGroupItem*                 插入的属性组
        */
        CPropertyGroupItem* InsertPropertyGroup(int index, int uniqueID, const QString& name, const QString& description);

        /*!
        *@brief                                      添加属性组
        *@param [in] int uniqueID               唯一标识
        *@param [in] const QString & name           属性组名称
        *@param [in] const QString & description    属性组描述
        *@return CPropertyGroupItem*                 添加的属性组
        */
        CPropertyGroupItem* AddPropertyGroup(int uniqueID, const QString& name, const QString& description);

        /*!
        *@brief                                      通过索引获取属性组
        *@param [in] int index                      索引
        *@return CPropertyGroupItem*                 查找的属性组
        */
        CPropertyGroupItem* GetPropertyGroupByIndex(int index) const;

        /*!
        *@brief                                      通过名称获取属性组
        *@param [in] const QString & name            名称
        *@return CPropertyGroupItem*                 查找的属性组
        */
        CPropertyGroupItem* GetPropertyGroupByName(const QString& name) const;

        /*!
        *@brief                                      通过唯一标识获取属性组
        *@param [in] int uniqueID
        *@return CPropertyGroupItem*
        */
        CPropertyGroupItem* GetPropertyGroupByUniqueID(int uniqueID) const;

        /*!
        *@brief                                      通过索引删除属性组
        *@param [in] int groupIndex                  属性组索引
        *@return bool                                true表示删除成功，false表示删除失败
        */
        bool RemovePropertyGroup(int groupIndex);

        /*!
        *@brief                                      删除所有属性组
        *@return bool                                true表示删除成功，false表示删除失败
        */
        bool RemoveAllPropertyGroup(); 

        /*!
        *@brief                                      获取所有属性组
        *@return vector<CPropertyGroupItem*>         所有属性组
        */
        const std::vector<CPropertyGroupItem*> &GetAllPropertyGroup() const;

        /*!
        *@brief                                      获取属性组数量
        *@return int                                 属性组数量
        */
        int GetPropertyGroupCount() const;

        /*!
        *@brief                                     指定位置插入属性
        *@param [in] int groupIndex                 属性组索引
        *@param [in] int index                      指定索引
        *@param [in] int uniqueID                   唯一标识
        *@param [in] const QString & name           属性名称
        *@param [in] const QString & description    属性描述
        *@param [in] const QVariant & value         属性值
        *@param [in] bool isEnable                  false表示只读
        *@param [in] GEditStyle editStyle           编辑样式
        *@return CPropertyItem*                     插入的属性
        */
        CPropertyItem* InsertProperty(int groupIndex, int index, int uniqueID, const QString& name, const QString& description, 
            const QVariant& value, bool isEnable, GEditStyle editStyle, bool bCanbeBind = false);

        /*!
        *@brief                                     添加属性
        *@param [in] int groupIndex                 属性组索引
        *@param [in] int uniqueID                   唯一标识
        *@param [in] const QString & name           属性名称
        *@param [in] const QString & description    属性描述
        *@param [in] const QVariant & value         属性值
        *@param [in] bool isEnable                  false表示只读
        *@param [in] GEditStyle editStyle           编辑样式
        *@return CPropertyItem*                     添加的属性
        */
        CPropertyItem* AddProperty(int groupIndex, int uniqueID, const QString& name, const QString& description, const QVariant& value, 
            bool isEnable, GEditStyle editStyle, bool bCanbeBind = false);

        /*!
        *@brief                                      通过属性索引获取属性
        *@param [in] int groupIndex                  属性组索引
        *@param [in] int nPropertyIndex              属性索引
        *@return CPropertyItem*                      查找的属性
        */
        CPropertyItem* GetPropertyByIndex(int groupIndex, int nPropertyIndex) const;

        /*!
        *@brief                                      通过属性名称获取属性
        *@param [in] int groupIndex                  属性组索引
        *@param [in] const QString & name            属性名称
        *@return CPropertyItem*                      查找的属性
        */
        CPropertyItem* GetPropertyByName(int groupIndex, const QString& name) const;

        /*!
        *@brief                                      通过唯一标识获取属性
        *@param [in] int uniqueID
        *@return CPropertyItem*
        */
        CPropertyItem* GetPropertyByUniqueID(int uniqueID) const;
        /*!
        *@brief                                     通过属性索引删除属性
        *@param [in] int groupIndex                 属性组索引
        *@param [in] int nPropertyIndex             属性索引
        *@return bool                               true表示删除成功，false表示删除失败
        */
        bool RemoveProperty(int groupIndex, int nPropertyIndex);
        /*!
        *@brief                                     通过属性名称删除属性
        *@param [in] int groupIndex                 属性组索引
        *@param [in] const QString & name           属性名称
        *@return bool                               true表示删除成功，false表示删除失败
        */
        bool RemoveProperty(int groupIndex, const QString& name);
        /*!
        *@brief                                     删除所有属性
        *@param [in] int groupIndex                 属性组索引
        *@return void
        */
        void RemoveAllPropertys(int groupIndex);
        /*!
        *@brief                                     获取属性数目
        *@param [in] int groupIndex                 属性组索引
        *@return int                                属性数目
        */
        int GetPropertyCount(int groupIndex) const;

        void SetBindButtonColomnVisible(bool bVisible);

        /*!
        *@brief                                      设置QtTreePropertyBrowser的名称
        *@param [in] const QString & name            名称
        *@return void
        */
        void SetTreePropertyBrowserName(const QString& name);

        /*!
        *@brief                                      获取QTreeWidget控件
        *@return QtPropertyEditorView*
        */
        QtPropertyEditorView* GetPropertyEditorView() const;

    protected slots:
        void OnPropertyValueChanged(QtProperty *property, const QVariant &val);
        void OnMouseLeave();

Q_SIGNALS:    
        void  FinishedEditing(); //自定义信号
        void  PropertyChanged(int groupIndex, int propertyIndex);
        void  sigPropertyBindButtonClicked(int uniqueID);
        void  sigPropertyEditButtonClicked(int uniqueID);
        void  DropDownListIndexChange(int groupIndex, int propertyIndex);
        void  sigHidePopup(QObject* obj);

    private:
        //构造或更新界面
        void Build(bool bRebuild = false);
        //删除所有属性项目
        void ClearAllProperty();

        virtual bool eventFilter(QObject *, QEvent *);

    private:
        std::unique_ptr<CPropertyInstanceSetting>  m_propertyInstanceSetting;//属性设置框中的配置信息
        std::unique_ptr<QtVariantPropertyManager>  m_variantManager;
        std::unique_ptr<QtVariantEditorFactory>    m_variantFactory;
        std::unique_ptr<QtTreePropertyBrowser>     m_propertyBrowser;
        bool                                       m_bButtonColomnShow;
    };

}

#endif //PROPERTYINSTANCPROPERTYSWIDGET_H
